﻿using System;
using System.Collections.Generic;
using System.Diagnostics.Contracts;
using System.Linq;
using System.Text;

namespace Isuka.Cola
{
    public static class DynamicLibrary
    {
        public static IDynamicLibrary Load(string libraryPath)
        {
            Contract.Requires<ArgumentException>(!string.IsNullOrWhiteSpace(libraryPath));
            Contract.Ensures(Contract.Result<IDynamicLibrary>() != null);


            // 暫定実装
            if (Environment.OSVersion.Platform != PlatformID.Win32NT)
            {
                throw new InvalidOperationException();
            }
            return new Win32.Win32DynamicLibrary(libraryPath);
        }

        public static TDelegate GetDelegate<TDelegate>(this IDynamicLibrary library, out TDelegate d, string name = null)
            where TDelegate : class
        {
            Contract.Requires<ArgumentNullException>(library != null, "library");
            Contract.Ensures(Contract.ValueAtReturn<TDelegate>(out d) != null);
            Contract.Ensures(Contract.Result<TDelegate>() != null);

            object wrk = library.GetDelegate(typeof(TDelegate));
            d = (TDelegate)wrk;
            return d;
        }

        public static Delegate GetDynamicDelegate(this IDynamicLibrary library, string signature)
        {
            Contract.Requires<ArgumentNullException>(library != null, "library");
            Contract.Requires<ArgumentException>(!String.IsNullOrWhiteSpace(signature));
            Contract.Ensures(Contract.Result<Delegate>() != null);

            var type = Auxiliaries.DynamicDelegateParser.CreateDelegate(signature);
            return library.GetDelegate(type);
        }
    }
}
